﻿#include "baidufaceapi.h"
#include <QImage>
#include <QBuffer>
#include <QInputDialog>
#include <QMessageBox>

const QString baiduTokenUrl = "https://aip.baidubce.com/oauth/2.0/token?grant_type=client_credentials&client_id=%1&client_secret=%2&";
const char *client_id = "VEc1cHdt1PFaV6snD68VRRyL";
const char *secret_id = "PQrGeda32ZNgjwpiph0dHQ8txqFoGARP";
const char *group_id = "100";


BaiduFaceAPI::BaiduFaceAPI(QObject *parent) : QObject(parent) {

}

QByteArray BaiduFaceAPI::imageToBase64(QString fileName) {
    QImage img(fileName);
    QByteArray ba;
    QBuffer buf(&ba);//用QByteArray构造QBuffer
    buf.open(QIODevice::WriteOnly);
    img.save(&buf, "PNG"); //把img 写入QBuffer

    QByteArray base64ImageData = ba.toBase64();//不包含编码头

    buf.close();

    return base64ImageData;
}

UfInfo BaiduFaceAPI::faceSearch(QString fileName) {
    const QString baiduImageUrl = "https://aip.baidubce.com/rest/2.0/face/v3/search?access_token=%1";
    QString accessToken;

    //得到图片的base64数据
    QString img = imageToBase64(fileName);

    //通过json的形式格式化请求体
    QJsonObject data;
    data.insert("image", QJsonValue(img));
    data.insert("image_type", QJsonValue("BASE64"));
    data.insert("group_id_list", QJsonValue(group_id));

    QJsonDocument doc(data);
    QByteArray dataArray = doc.toJson();

    //获取access_token
    QByteArray replyData; //保存回复信息
    QString url = QString(baiduTokenUrl).arg(client_id).arg(secret_id);

    QMap<QString, QString> header; //封装头部信息
    header.insert(QString("Content-Type"), QString("application/json"));

    // 获取token时不需要传图片数据,传了会导致速度变慢
    QByteArray nullDataArray;
    bool result = Http::post_syns(url, header, nullDataArray, replyData);
    if(result) {
        QJsonObject obj = QJsonDocument::fromJson(replyData).object();
        accessToken = obj.value("access_token").toString();
    } else {
        qDebug() << "accessToken failed";
    }
    qDebug() << "access result:" << result << "accessToken:" << accessToken;

    //获取人脸识别结果
    replyData.clear();
    QString imgurl = baiduImageUrl.arg(accessToken);
    result = Http::post_syns(imgurl, header, dataArray, replyData);

    qDebug() << "face result:" << result;

    if(result) {
        qDebug() << "replyData:" << replyData.data();
        //解析json
#if 0
        {
            "error_code": 0,
"error_msg": "SUCCESS"
            ,
            "log_id": 480697651,
            "timestamp": 1670566080,
            "cached": 0,
"result": {
"face_token": "b18b90bdcbe5adae68d93c1cbd643211"
                ,
"user_list":
                [ {
"group_id":"100",
"user_id":"1670565908",
"user_info":"\u4f55\u6c38\u6210",
                    "score":95.685073852539
                }
                ]
            }
        }
#endif

        UfInfo ufInfo;

        QJsonDocument doc = QJsonDocument::fromJson(replyData);
        QJsonObject docObject = doc.object();
        QJsonObject resultObject = docObject.value("result").toObject();
        QJsonArray userlistArray = resultObject.value("user_list").toArray();
        ufInfo.userId = userlistArray.at(0).toObject().value("user_id").toString();
        ufInfo.username = userlistArray.at(0).toObject().value("user_info").toString();
        double score = userlistArray.at(0).toObject().value("score").toDouble();

        qDebug() << "score:" << score;
        qDebug() << "username:" << ufInfo.username;
        if(score >= 90.0) { //阈值
            return ufInfo;
        }
    }
    UfInfo ufInfo;
    return ufInfo;
}

bool BaiduFaceAPI::faceRegister(QString fileName, QString userId, QString userName) {
    const QString baiduImageUrl = "https://aip.baidubce.com/rest/2.0/face/v3/faceset/user/add?access_token=%1";
    QString accessToken;

    //得到图片的base64数据
    QString img = imageToBase64(fileName);

    //通过json的形式格式化请求体
    QJsonObject data;
    data.insert("image", QJsonValue(img));
    data.insert("image_type", QJsonValue("BASE64"));
    data.insert("group_id", QJsonValue(group_id));
    data.insert("user_id", QJsonValue(userId));
    data.insert("user_info", QJsonValue(userName));


    QJsonDocument doc(data);
    QByteArray dataArray = doc.toJson();

    //获取access_token
    QByteArray replyData; //保存回复信息
    QString url = QString(baiduTokenUrl).arg(client_id).arg(secret_id);

    QMap<QString, QString> header; //封装头部信息
    header.insert(QString("Content-Type"), QString("application/json"));

    QByteArray nullDataArray;
    bool result = Http::post_syns(url, header, nullDataArray, replyData);
    if(result) {
        QJsonObject obj = QJsonDocument::fromJson(replyData).object();

        accessToken = obj.value("access_token").toString();
    } else {
        qDebug() << "accessToken failed";
    }
    qDebug() << "access result:" << result << "accessToken:" << accessToken;


    //获取人脸注册结果
    replyData.clear();
    QString imgurl = baiduImageUrl.arg(accessToken);
    result = Http::post_syns(imgurl, header, dataArray, replyData);

    qDebug() << "face result:" << result;

    if(result) {
        qDebug() << "replyData:" << replyData.data();
        //不需要解析json
#if 0
        {
"face_token": "2fa64a88a9d5118916f9a303782a97d3"
            ,
"location": {
                "left": 117,
                "top": 131,
                "width": 172,
                "height": 170,
                "rotation": 4
            }
        }
#endif
    }

    return true;
}

bool BaiduFaceAPI::faceUpdate(QString fileName, QString userId, QString username) {
    // 点击按钮时，会先拍摄当前照片，然后通过人脸搜索接口，获取当前人脸的user_id，再进行人脸更新

    //搜索人脸库是否存在 该人脸
//    UfInfo ufInfo = faceSearch(fileName);
//    if(ufInfo.username.isEmpty()) {
//        return false;
//    }
    //user_id

    const QString baiduImageUrl = "https://aip.baidubce.com/rest/2.0/face/v3/faceset/user/update?access_token=%1";
    QString accessToken;

    //得到图片的base64数据
    QString img = imageToBase64(fileName);

    //通过json的形式格式化请求体
    QJsonObject data;
    data.insert("image", QJsonValue(img));
    data.insert("image_type", QJsonValue("BASE64"));
    data.insert("group_id", QJsonValue(100));
    data.insert("user_id", QJsonValue(userId));
    data.insert("user_info", QJsonValue(username));


    QJsonDocument doc(data);
    QByteArray dataArray = doc.toJson();

    //获取access_token
    QByteArray replyData; //保存回复信息
    QString url = QString(baiduTokenUrl).arg(client_id).arg(secret_id);

    QMap<QString, QString> header; //封装头部信息
    header.insert(QString("Content-Type"), QString("application/json"));

    QByteArray nullDataArray;
    bool result = Http::post_syns(url, header, nullDataArray, replyData);
    if(result) {
        QJsonObject obj = QJsonDocument::fromJson(replyData).object();

        accessToken = obj.value("access_token").toString();
    } else {
        qDebug() << "accessToken failed";
    }
    qDebug() << "access result:" << result << "accessToken:" << accessToken;


    //获取人脸更新结果
    replyData.clear();
    QString imgurl = baiduImageUrl.arg(accessToken);
    result = Http::post_syns(imgurl, header, dataArray, replyData);

    qDebug() << "face result:" << result;

    if(result) {
        qDebug() << "replyData:" << replyData.data();

        return true;
        //不需要解析json
#if 0
        {
"face_token": "2fa64a88a9d5118916f9a303782a97d3"
            ,
"location": {
                "left": 117,
                "top": 131,
                "width": 172,
                "height": 170,
                "rotation": 4
            }
        }
#endif
    }

    return false;
}
